package com.richie696.catalina;


import java.io.FileInputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

public class WebAppClassLoader extends URLClassLoader {

    /**
     * 使用这个自定义类加载器时候
     * 绑定指定的一个被加载类的当前目录的路径
     */
    private final String path;
    private final Map<String, Class<?>> resourceEntries = new ConcurrentHashMap<>(10);


    public WebAppClassLoader(String path) {
        super(new URL[0]);
        this.path = path;
    }

    @Override
    public Class<?> findClass(String className) throws ClassNotFoundException {
        if (Objects.isNull(className) || className.isBlank()) {
            throw new ClassNotFoundException(className);
        }
        if (resourceEntries.containsKey(className)) {
            return resourceEntries.get(className);
        }
        String name = className.replaceAll("\\.", "/");
        String absolutePath = this.path + "/WEB-INF/classes/" + name + ".class";

        byte[] fileBytes = loadBytes(absolutePath);
        Class<?> clazz = defineClass(className, fileBytes, 0, fileBytes.length);
        if (Objects.isNull(clazz)) {
            clazz = super.findClass(name);
        }
        resourceEntries.put(className, clazz);
        return clazz;
    }

    private byte[] loadBytes(String absolutePath) throws ClassNotFoundException {
        try (FileInputStream fis = new FileInputStream(absolutePath)) {
            int length = fis.available();
            byte[] bytes = new byte[length];
            //noinspection ResultOfMethodCallIgnored
            fis.read(bytes);
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ClassNotFoundException(absolutePath, e);
        }
    }

}
